using System;
using System.Collections.Generic;
using System.Text;
using NHibernate;
using NHibernate.Mapping.Attributes;
using Lib;

namespace Persistance.Model
{

    /*
     * User Object Specification
     * 
     * UserID (int) --> The unique ID associated with this user. The networkID of the user on RIMNET
     * FullName (varchar) --> The Fullname of the user. Decided to store this for convenience sake.
     * SecurityLevel (int) --> A number between 1 and 30 to denote the users security clearance. Left a lot of room in case different user types are added in the future.
     * */

    [Serializable]
    [Class]
    public class Users
    {

        public Users()
        {
            _userID = null;
        }

        public Users(string userID)
        {
            this._userID = userID;
        }

        #region " Mapping "

        private int _numericUserID;         //This is needed for NH. NH only accepts numeric primary keys
        //NHIBER: Setts the primary key to ID
        [Id(Name = "NumericUserID")]
        [Generator(1, Class = "native")]
        public virtual int NumericUserID
        {
            get { return _numericUserID; }
            set { _numericUserID = value; }
        }


        private string _userID;
        [Property(Length = 50)]
        [Property(Unique = true)]
        public virtual string UserID
        {
            get { return _userID; }
            set { _userID = value; }
        }

        private string _fullName;
        [Property(Length = 20)]
        public virtual string FullName
        {
            get { return _fullName; }
            set { _fullName = value; }
        }

        private int _securityLevel;
        [Property(Type = "int")]
        public virtual int SecurityLevel
        {
            get { return _securityLevel; }
            set { _securityLevel = value; }
        }

        private IList<ProblemCauses> _problemCauses = new List<ProblemCauses>();
        [OneToMany(3, ClassType = typeof(ProblemCauses))]
        public virtual IList<ProblemCauses> ProblemCauses
        {
            get { return _problemCauses; }
            set { _problemCauses = value; }
        }

        private IList<Problem> _problems = new List<Problem>();
        [Bag(1, Inverse = true, Cascade = CascadeStyle.None)]
        [Key(2, Column = "AuthorID")]
        [OneToMany(1, ClassType = typeof(Problem))]
        public virtual IList<Problem> Problems
        {
            get { return _problems; }
            set { _problems = value; }
        }

        private IList<Situation> _situations = new List<Situation>();
        [Bag(1, Inverse = true, Cascade = CascadeStyle.None)]
        [Key(2, Column = "AuthorID")]
        [OneToMany(3, ClassType = typeof(Situation))]
        public virtual IList<Situation> Situations
        {
            get { return _situations; }
            set { _situations = value; }
        }


        private IList<Users> _coaches = new List<Users>();
        [Bag(1, BatchSize = 100, Name = "Coaches", Table = "Coaches", Cascade = CascadeStyle.None)]
        [Key(2, Column = "AuthorID")]
        [ManyToMany(3, ClassType = typeof(Users), Column = "CoachID")]
        public virtual IList<Users> Coaches
        {
            get { return _coaches; }
            set { _coaches = value; }
        }

        private IList<Users> _authors = new List<Users>();
        [Bag(1, BatchSize = 100, Name = "Authors", Table = "Coaches", Cascade = CascadeStyle.None)]
        [Key(2, Column = "CoachID")]
        [ManyToMany(3, ClassType = typeof(Users), Column = "AuthorID")]
        public virtual IList<Users> Authors
        {
            get { return _authors; }
            set { _authors = value; }
        }

        #endregion


        public virtual Users getMyInfo()
        {
            ISession sess = Persistor.CurrentSession;
            try
            {
                IQuery q = sess.CreateQuery("from Users u where u.UserID = :ID");
                q.SetString("ID", _userID);
                List<Users> results = (List<Users>)q.List<Users>();

                if (results[0] == null)
                {
                    throw new Exception("No User Found!");
                }

                sess.Flush();
                return results[0];
            }
            catch (Exception e)
            {
                throw new Exception(e.Message, e);
            }
        }

        public virtual void Create()
        {
            ISession sess = Persistor.CurrentSession;
            try
            {
                sess.Transaction.Begin();
                sess.Save(this);
                sess.Transaction.Commit();
                sess.Flush();
            }
            catch (Exception e)
            {
                sess.Transaction.Rollback();
                throw new Exception("akljsghp", e);
            }
        }

    }
}
